#include <stdio.h>
#include <stdlib.h>
#define CAPACITY 30
///////////////////////////////////////////////
// Data structures for the Sum language.
enum Exp_Kind_t {EXP_INT, EXP_SUM};
struct Exp_t
{
  enum Exp_Kind_t kind;
};

struct Exp_Int
{
  enum Exp_Kind_t kind;
  int i;
};

struct Exp_Sum
{
  enum Exp_Kind_t kind;
  struct Exp_t *left;
  struct Exp_t *right;
};

// "constructors"
struct Exp_t *Exp_Int_new (int i)
{
  struct Exp_Int *p = malloc (sizeof(*p));
  p->kind = EXP_INT;
  p->i = i;
  return (struct Exp_t *)p;
}

struct Exp_t *Exp_Sum_new (struct Exp_t *left, struct Exp_t *right)
{
  struct Exp_Sum *p = malloc (sizeof(*p));
  p->kind = EXP_SUM;
  p->left = left;
  p->right = right;
  return (struct Exp_t *)p;
}

// "printer"
void Exp_print (struct Exp_t *exp)
{
  switch (exp->kind){
  case EXP_INT:{
    struct Exp_Int *p = (struct Exp_Int *)exp;
    printf ("%d", p->i);
    break;
  }
  case EXP_SUM:{
    struct Exp_Sum *p = (struct Exp_Sum *)exp;
    Exp_print (p->left);
    printf ("+");
    Exp_print (p->right);
    break;
  }
  default:
    break;
  }
}
// "stack structure"
struct stack_char{
	char * arr;
	int top;
	int cap;
};
struct stack_char * stack_char_new(int capacity){
	struct stack_char * st = (struct stack_char *)malloc(sizeof(struct stack_char));
	st->arr = (char *)malloc(sizeof(char) * capacity);
	st->top = 0;
	st->cap = capacity;
	return st;
}
void push(struct stack_char * st, char ch){
	if (st->top == st->cap){ printf("Stack is full"); exit(-2);}
	st->arr[st->top] = ch;
	st->top++;
}
char pop(struct stack_char * st){
	if (0 == st->top){ printf("Stack is empty"); exit(-2);}
	return st->arr[--st->top];
}
// "queue structure"
struct queue{
	char * arr, * head, *tail;
	int cap;
};
struct queue * queue_new(int capacity){
	struct queue * qu = (struct queue *)malloc(sizeof(struct queue));
	qu->arr = (char *)malloc(sizeof(char) * capacity);
	qu->head = qu->tail = qu->arr;
	qu->cap = capacity;
	return qu;
}
void inqueue(struct queue * qu,char ch){
	if (qu->tail+1 == qu->head || (qu->tail == qu->arr+qu->cap-1 && qu->head == qu->arr)) exit(-2);
	if (qu->tail == qu->arr+qu->cap-1) qu->tail = qu->arr;
	*(qu->tail++) = ch;
}
char dequeue(struct queue * qu){
	if (qu->tail == qu->head) exit(-2);
	return *(qu->head++);
}

//struct stack_char * numbers   = 0;
//struct stack_char * operators = 0;
struct queue * numbers = 0, * operators = 0;
struct Exp_t      *	exp 	  = 0;

void parser_init(char * str){
	//numbers   = stack_char_new(CAPACITY);
 	//operators = stack_char_new(CAPACITY/2);
	numbers = queue_new(CAPACITY);
	operators = queue_new(CAPACITY/2);
	if(!str) exit(-1);
	char *p = str;
	while(*p){
		if ('0' <= *p && '9' >= *p)
			//push(numbers,*p);
			inqueue(numbers,*p);
		else if ('+' == *p)
			//push(operators,*p);
			inqueue(operators,*p);
		p++;
	}
	//exp = Exp_Int_new(pop(numbers)-'0');
	exp = Exp_Int_new(dequeue(numbers)-'0');
}
void parser(){
//	while(operators->top != 0 && pop(operators))
	while(operators->tail != operators->head && dequeue(operators))
		exp = Exp_Sum_new((struct Exp_t *) exp,
			//Exp_Int_new(pop(numbers) - '0'));
			Exp_Int_new(dequeue(numbers) - '0'));
}

int main(int argc,char **argv){
	parser_init(argv[1]);
	parser();
	Exp_print(exp);

	return 0;
}
